From: Ashe Connor Date: Thu, 19 Oct 2017 05:15:16 +0000 (+1100) Subject: Try current_exe, then argv0 canonicalize, then PATH X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~5^2~28^2~3 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=6ad2b9b28d4f6d206ba877bfccad10b423a684ba;p=cargo.git Try current_exe, then argv0 canonicalize, then PATH --- diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 039993567..4f523ed07 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -153,10 +153,42 @@ impl Config { /// Get the path to the `cargo` executable pub fn cargo_exe(&self) -> CargoResult<&Path> { - self.cargo_exe.get_or_try_init(|| - env::current_exe().and_then(|path| path.canonicalize()) - .chain_err(|| "couldn't get the path to cargo executable") - ).map(AsRef::as_ref) + self.cargo_exe.get_or_try_init(|| { + fn from_current_exe() -> CargoResult { + env::current_exe() + .and_then(|path| path.canonicalize()) + .map_err(CargoError::from) + } + + fn from_argv() -> CargoResult { + env::args_os() + .next() + .ok_or(CargoError::from("no argv[0]")) + .map(PathBuf::from) + .and_then(|argv0| argv0.canonicalize().or_else(|_| probe_path(argv0))) + } + + fn probe_path(argv0: PathBuf) -> CargoResult { + // canonicalize failed, probe PATH if no dir sep in argv0 + if argv0.components().count() > 1 { + return Err(CargoError::from("no cargo executable candidate found")); + } + + let paths = env::var_os("PATH").ok_or(CargoError::from("no PATH"))?; + for path in env::split_paths(&paths) { + let candidate = PathBuf::from(path).join(&argv0); + if candidate.is_file() { + return candidate.canonicalize().map_err(CargoError::from); + } + } + + Err(CargoError::from("no cargo executable candidate found in PATH")) + } + + from_current_exe() + .or_else(|_| from_argv()) + .chain_err(|| "couldn't get the path to cargo executable") + }).map(AsRef::as_ref) } pub fn values(&self) -> CargoResult<&HashMap> {